home *** CD-ROM | disk | FTP | other *** search
/ Practical Algorithms for Image Analysis / Practical Algorithms for Image Analysis.iso / TARFILE.GZ / tarfile / ch_3.4 / peak / peak.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-11  |  6.2 KB  |  194 lines

  1. /* 
  2.  * peak.c
  3.  * 
  4.  * Practical Algorithms for Image Analysis
  5.  * 
  6.  * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
  7.  */
  8.  
  9. /* PEAK:        program finds a peak in a given area using the
  10.  *                    converging squares algorithm, a multi-resolution approach.
  11.  *
  12.  */
  13.  
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <tiffimage.h>          /* tiff info on images */
  18. #include <images.h>
  19. extern void print_sos_lic ();
  20.  
  21. #define SIZE_FINAL_DFLT 5       /* final size of converging squares */
  22. #define INBOUNDX(X) ((X) >= 0 && (X) < imgSize.x)
  23. #define INBOUNDY(Y) ((Y) >= 0 && (Y) < imgSize.y)
  24.  
  25. int usage (short);
  26. int input (int, char **, long *, long *, long *, long *, short *);
  27. long convsqrs (unsigned char *, long, long, int, int, int, int,
  28.                int *, int *);
  29.  
  30. main (argc, argv)
  31.      int argc;
  32.      char *argv[];
  33. {
  34.   Image *imgI;                  /* I/O image structure */
  35.   unsigned char **image;        /* input/output image */
  36.   unsigned char *pImage;        /* pointer to image array */
  37.   long x0, y0;                  /* initial top-left region coord.s */
  38.   long size0, sizeF;            /* initial/final region size for peak detection */
  39.   short dFlag;                  /* if =1, displays path of conv. sqrs to peak */
  40.   struct point imgSize;         /* image dimensions */
  41.   long rowPeak, colPeak;        /* location of peak */
  42.   long x, y, i, j;
  43.  
  44. /* read user parameter values */
  45.   if ((input (argc, argv, &x0, &y0, &size0, &sizeF, &dFlag)) < 0)
  46.     return (-1);
  47.  
  48. /* open image */
  49.   imgI = ImageIn (argv[1]);
  50.   image = imgI->img;
  51.   imgSize.y = ImageGetHeight (imgI);
  52.   imgSize.x = ImageGetWidth (imgI);
  53.   printf ("image size is %dx%d\n", imgSize.x, imgSize.y);
  54.  
  55.   pImage = (unsigned char *) calloc (imgSize.x * imgSize.y,
  56.                                      sizeof (unsigned char));
  57.   for (y = 0, i = 0; y < imgSize.y; y++)
  58.     for (x = 0; x < imgSize.x; x++)
  59.       pImage[i++] = image[y][x];
  60.  
  61. /* find peaks */
  62.   if (size0 == -1)
  63.     size0 = (imgSize.x < imgSize.y) ? imgSize.x : imgSize.y;
  64.   convsqrs (pImage, imgSize.x, imgSize.y, y0, x0, size0, sizeF,
  65.             (int *) &rowPeak, (int *) &colPeak);
  66.   printf ("rowPeak = %d, colPeak = %d\n", rowPeak, colPeak);
  67.  
  68. /* display peak */
  69.   if (dFlag) {                  /* display peak if flag set */
  70.     for (i = rowPeak - 3; i <= rowPeak + 3; i++) {
  71.       if (INBOUNDY (i)) {
  72.         if (INBOUNDX (colPeak - 3))
  73.           image[i][colPeak - 3] = (image[i][colPeak - 3] > 128) ? 0 : 255;
  74.         if (INBOUNDX (colPeak + 4))
  75.           image[i][colPeak + 3] = (image[i][colPeak + 3] > 128) ? 0 : 255;
  76.       }
  77.     }
  78.     for (j = colPeak - 2; j <= colPeak + 2; j++) {
  79.       if (INBOUNDX (j)) {
  80.         if (INBOUNDY (rowPeak - 3))
  81.           image[rowPeak - 3][j] = (image[rowPeak - 3][j] > 128) ? 0 : 255;
  82.         if (INBOUNDY (rowPeak + 4))
  83.           image[rowPeak + 3][j] = (image[rowPeak + 3][j] > 128) ? 0 : 255;
  84.       }
  85.     }
  86.   }
  87.  
  88.   ImageOut (argv[2], imgI);
  89.   return (0);
  90. }
  91.  
  92. /* USAGE:       function gives instructions on usage of program
  93.  *                    usage: usage (flag)
  94.  *              When flag is 1, the long message is given, 0 gives short.
  95.  */
  96.  
  97. int
  98. usage (flag)
  99.      short flag;                /* flag =1 for long message; =0 for short message */
  100. {
  101.  
  102. /* print short usage message or long */
  103.   printf ("USAGE: peak inimg outimg -x X0 -y Y0 -s SIZE_INITIAL\n");
  104.   printf ("                        [-f SIZE_FINAL] [-d] [-L]\n");
  105.   if (flag == 0)
  106.     return (-1);
  107.  
  108.   printf ("\npeak finds peak in given region of an image.\n");
  109.   printf ("NOTE: this program finds ONE peak based on iteratively\n");
  110.   printf ("      reducing the region size; therefore the initially chosen\n");
  111.   printf ("      region location and size strongly affects which peak will be chosen.\n");
  112.   printf ("      this program works best for convex shapes with smoothly\n");
  113.   printf ("      changing slopes; it may give strange results for geometric shapes,\n");
  114.   printf ("      especially those with edges aligned to horizontal or vertical axes.\n\n");
  115.   printf ("ARGUMENTS:\n");
  116.   printf ("            inimg: input image filename (TIF)\n");
  117.   printf ("           outimg: output image filename (TIF)\n");
  118.   printf ("            -x X0: top left x-coord of region\n");
  119.   printf ("            -y Y0: top left y-coord of region\n");
  120.   printf ("  -s SIZE_INITIAL: square size of region in which to find peak\n");
  121.   printf ("                   NOTE: -x, -y and -s values must\n");
  122.   printf ("                   be set by the user\n\n");
  123.   printf ("OPTIONS:\n");
  124.   printf ("    -f SIZE_FINAL: final square size, after which peak pixel\n");
  125.   printf ("               -d: to display peak location.\n");
  126.   printf ("               -L: print Software License for this module\n");
  127.  
  128.   return (-1);
  129. }
  130.  
  131.  
  132. /* INPUT:       function reads input parameters
  133.  *                  usage: input (argc, argv, &x0, &y0, &size0, &sizeF, &dFlag)
  134.  */
  135.  
  136. #define USAGE_EXIT(VALUE) {usage (VALUE); return (-1);}
  137.  
  138. int
  139. input (argc, argv, x0, y0, size0, sizeF, dFlag)
  140.      int argc;
  141.      char *argv[];
  142.      long *x0, *y0;             /* initial top-left region coord.s */
  143.      long *size0, *sizeF;       /* initial/final region size for peak detection */
  144.      short *dFlag;              /* if =1, displays path of conv. sqrs. */
  145. {
  146.   long n;
  147.  
  148.   if (argc == 1)
  149.     USAGE_EXIT (1);
  150.   if (argc == 2)
  151.     USAGE_EXIT (0);
  152.  
  153.   *x0 = *y0 = -1;
  154.   *size0 = -1;
  155.   *sizeF = SIZE_FINAL_DFLT;
  156.   *dFlag = 0;
  157.  
  158.   for (n = 3; n < argc; n++) {
  159.     if (strcmp (argv[n], "-x") == 0) {
  160.       if (++n == argc || argv[n][0] == '-')
  161.         USAGE_EXIT (0);
  162.       *x0 = atol (argv[n]);
  163.     }
  164.     else if (strcmp (argv[n], "-y") == 0) {
  165.       if (++n == argc || argv[n][0] == '-')
  166.         USAGE_EXIT (0);
  167.       *y0 = atol (argv[n]);
  168.     }
  169.     else if (strcmp (argv[n], "-s") == 0) {
  170.       if (++n == argc || argv[n][0] == '-')
  171.         USAGE_EXIT (0);
  172.       *size0 = atol (argv[n]);
  173.     }
  174.     else if (strcmp (argv[n], "-f") == 0) {
  175.       if (++n == argc || argv[n][0] == '-')
  176.         USAGE_EXIT (0);
  177.       *sizeF = atol (argv[n]);
  178.     }
  179.     else if (strcmp (argv[n], "-d") == 0)
  180.       *dFlag = 1;
  181.     else if (strcmp (argv[n], "-L") == 0) {
  182.       print_sos_lic ();
  183.       exit (0);
  184.     }
  185.     else
  186.       USAGE_EXIT (0);
  187.   }
  188.  
  189.   if (*x0 == -1 || *y0 == -1 || *size0 == -1)
  190.     USAGE_EXIT (1);
  191.  
  192.   return (0);
  193. }
  194.